/*
 * Copyright (C) 2015-2016  Nicola Spanti (RyDroid) <dev@nicola-spanti.info>
 * 
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 * 
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Affero General Public License for more details.
 * 
 * You should have received a copy of the GNU Affero General Public License
 * along with this program.  If not, see <https://www.gnu.org/licenses/>.
 */


/**
 * @file
 * @brief Useful functions for a player playing
 */


#ifndef PLANET_WARS_2D_RT_CORE_MODEL_PLAYER_PLAYING_FUNCTIONS_H
#define PLANET_WARS_2D_RT_CORE_MODEL_PLAYER_PLAYING_FUNCTIONS_H


#include "PlanetWars2dRT-core/specific/model/player.h"
#include "PlanetWars2dRT-core/specific/model/universe_planets.h"
#include "PlanetWars2dRT-core/specific/model/universe_ships.h"


typedef ship_t* ship_ptr;
DEFINE_VECTOR_GENERIC_STATIC(ship_ptr)


EXTERN_C_BEGIN


size_t
universe_get_nb_planets_of_player_index(const universe_t* universe,
					unsigned char player_index);

static inline
size_t
universe_get_nb_planets_not_of_player_index(const universe_t* universe,
					    unsigned char player_index)
{
  return
    universe_get_nb_planets(universe) -
    universe_get_nb_planets_of_player_index(universe, player_index);
}

/**
 * @return The number of neutral planets of a universe
 */
static inline
size_t
universe_get_nb_neutral_planets(const universe_t* universe)
{
  return universe_get_nb_planets_of_player_index(universe,
						 NULL_PLAYER_INDEX);
}

/**
 * @return The number of not neutral planets of a universe
 */
static inline
size_t
universe_get_nb_not_neutral_planets(const universe_t* universe)
{
  return
    universe_get_nb_planets(universe) -
    universe_get_nb_neutral_planets(universe);
}

/**
 * @param[out] nb Number of planets
 */
const planet_t**
universe_get_planets_of_player_index(const universe_t* universe,
				     unsigned char player_index,
				     size_t* nb);

/**
 * @param[out] nb Number of planets
 */
const planet_t**
universe_get_planets_not_of_player_index(const universe_t* universe,
					 unsigned char player_index,
					 size_t* nb);

/**
 * @param[out] nb Number of neutral planets
 */
static inline
const planet_t**
universe_get_neutral_planets(const universe_t* universe,
			     size_t* nb)
{
  return universe_get_planets_of_player_index(universe,
					      NULL_PLAYER_INDEX,
					      nb);
}

/**
 * @param[out] nb Number of not neutral planets
 */
static inline
const planet_t**
universe_get_not_neutral_planets(const universe_t* universe,
				 size_t* nb)
{
  return universe_get_planets_not_of_player_index(universe,
						  NULL_PLAYER_INDEX,
						  nb);
}

/**
 * @param[out] nb Number of positions
 */
position_2d_uint*
universe_get_center_positions_of_planets_not_of_player_index(const universe_t* universe,
							     unsigned char player_index,
							     size_t* nb);

position_2d_uint
universe_get_center_position_of_planets_of_player_index(const universe_t* universe,
							unsigned char player_index);

position_2d_uint
universe_get_center_position_of_planets_not_of_player_index(const universe_t* universe,
							    unsigned char player_index);


size_t
universe_get_nb_ships_of_player_index(const universe_t* universe,
				      unsigned char player_index);

static inline
size_t
universe_get_nb_ships_not_of_player_index(const universe_t* universe,
					  unsigned char player_index)
{
  return
    universe_get_nb_ships(universe) -
    universe_get_nb_ships_of_player_index(universe, player_index);
}

ship_t**
universe_get_ships_of_player_index(universe_t* universe,
				   unsigned char player_index,
				   size_t* nb);

ship_t**
universe_get_ships_not_of_player_index(universe_t* a_universe,
				       unsigned char player_index,
				       size_t* nb);

/**
 * @return Number of ships asked to move to the given position.
 */
size_t
universe_ships_of_player_index_go_to(universe_t* a_universe,
				     unsigned char player_index,
				     const position_2d_uint* position_to_go);

size_t
universe_get_nb_ships_of_player_index_in_rectangle(const universe_t* a_universe,
						   unsigned char player_index,
						   const position_2d_uint* pos,
						   const size_2d_uint* size);

vector_ship_ptr
universe_get_vector_ships_of_player_index_in_rectangle(universe_t* a_universe,
						       unsigned char player_index,
						       const position_2d_uint* pos,
						       const size_2d_uint* size)
  __attribute__((warn_unused_result));


EXTERN_C_END


#endif
